package org.evej.apiparser.model.character;

import org.evej.apiparser.model.ApiDocumentModel;
import org.evej.model.Augmentation;

import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * API model for the character sheet.
 *
 * The model is immutable. Use the static Builder to construct instances.
 * The CharacterSheetHandler produces instances of this class.
 *
 * @see Builder
 * @see org.evej.apiparser.parser.handler.character.CharacterSheetHandler
 */
public class ApiCharacterSheet implements ApiDocumentModel {

    private static final long serialVersionUID = 1879363859L;

    private final long characterID;
    private final String name;
    private final String race;
    private final Date dateOfBirth;
    private final String bloodLine;
    private final String ancestry;
    private final String gender;
    private final String corporationName;
    private final long corporationID;
    private final double balance;
    private final Set<Augmentation> augmentations;
    private final int intelligence;
    private final int memory;
    private final int charisma;
    private final int perception;
    private final int willpower;
    private final Set<ApiSkill> skills;
    private final Set<Integer> certificates;
    private final ApiCoorporationRoles coorporationRoles;
    private final Set<CoorporationTitle> coorporationTitles;

    private ApiCharacterSheet(Builder builder) {
        this.characterID = builder.characterID;
        this.name = builder.name;
        this.race = builder.race;
        if (builder.dateOfBirth != null) {
            this.dateOfBirth = new Date(builder.dateOfBirth.getTime());
        } else {
            this.dateOfBirth = new Date();
        }
        this.bloodLine = builder.bloodLine;
        this.ancestry = builder.ancestry;
        this.gender = builder.gender;
        this.corporationName = builder.corporationName;
        this.corporationID = builder.corporationID;
        this.balance = builder.balance;
        this.augmentations = builder.augmentations;
        this.intelligence = builder.intelligence;
        this.memory = builder.memory;
        this.charisma = builder.charisma;
        this.perception = builder.perception;
        this.willpower = builder.willpower;
        this.skills = builder.skills;
        this.certificates = builder.certificates;
        this.coorporationRoles = builder.coorporationRoles;
        this.coorporationTitles = builder.coorporationTitles;
    }

    public long getCharacterID() {
        return characterID;
    }

    public String getName() {
        return name;
    }

    public String getRace() {
        return race;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public String getBloodLine() {
        return bloodLine;
    }

    public String getAncestry() {
        return ancestry;
    }

    public String getGender() {
        return gender;
    }

    public String getCorporationName() {
        return corporationName;
    }

    public long getCorporationID() {
        return corporationID;
    }

    public double getBalance() {
        return balance;
    }

    public Set<Augmentation> getAugmentations() {
        return augmentations;
    }

    public int getIntelligence() {
        return intelligence;
    }

    public int getMemory() {
        return memory;
    }

    public int getCharisma() {
        return charisma;
    }

    public int getPerception() {
        return perception;
    }

    public int getWillpower() {
        return willpower;
    }

    public Set<ApiSkill> getSkills() {
        return skills;
    }

    public Set<Integer> getCertificates() {
        return certificates;
    }

    public ApiCoorporationRoles getCoorporationRoles() {
        return coorporationRoles;
    }

    public Set<CoorporationTitle> getCoorporationTitles() {
        return coorporationTitles;
    }


    /**
     * Builder for constructing instances of ApiCharacterSheet.
     */
    public static class Builder {

        private ApiCoorporationRoles.Builder coorporationBuilder = new ApiCoorporationRoles.Builder();

        private long characterID;
        private String name;
        private String race;
        private Date dateOfBirth;
        private String bloodLine;
        private String ancestry;
        private String gender;
        private String corporationName;
        private long corporationID;
        private double balance;
        private Set<Augmentation> augmentations = new HashSet<>();
        private int intelligence;
        private int memory;
        private int charisma;
        private int perception;
        private int willpower;
        private Set<ApiSkill> skills = new LinkedHashSet<>();
        private Set<Integer> certificates = new LinkedHashSet<>();
        private ApiCoorporationRoles coorporationRoles;
        private Set<CoorporationTitle> coorporationTitles = new LinkedHashSet<>();

        public Builder() {
        }

        public Builder setCharacterID(long id) {
            this.characterID = id;
            return this;
        }

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setRace(String race) {
            this.race = race;
            return this;
        }

        public Builder setDateOfBirth(Date dateOfBirth) {
            this.dateOfBirth = dateOfBirth;
            return this;
        }

        public Builder setBloodLine(String bloodLine) {
            this.bloodLine = bloodLine;
            return this;
        }

        public Builder setAncestry(String ancestry) {
            this.ancestry = ancestry;
            return this;
        }

        public Builder setGender(String gender) {
            this.gender = gender;
            return this;
        }

        public Builder setCorporationName(String corporationName) {
            this.corporationName = corporationName;
            return this;
        }

        public Builder setCorporationID(long corporationID) {
            this.corporationID = corporationID;
            return this;
        }

        public Builder setBalance(double balance) {
            this.balance = balance;
            return this;
        }

        public Builder addAugmentation(Augmentation augmentation) {
            this.augmentations.add(augmentation);
            return this;
        }

        public Builder setIntelligence(int intelligence) {
            this.intelligence = intelligence;
            return this;
        }

        public Builder setMemory(int memory) {
            this.memory = memory;
            return this;
        }

        public Builder setCharisma(int charisma) {
            this.charisma = charisma;
            return this;
        }

        public Builder setPerception(int perception) {
            this.perception = perception;
            return this;
        }

        public Builder setWillpower(int willpower) {
            this.willpower = willpower;
            return this;
        }

        public Builder addSkill(ApiSkill skill) {
            this.skills.add(skill);
            return this;
        }

        public Builder addCertificate(int certifacteId) {
            certificates.add(certifacteId);
            return this;
        }

        public Builder addCoorporationRole(ApiCoorporationRole role) {
            coorporationBuilder.addRole(role);
            return this;
        }

        public Builder addCoorporationRoleAtHQ(ApiCoorporationRole role) {
            coorporationBuilder.addRoleAtHQ(role);
            return this;
        }

        public Builder addCoorporationRoleAtBase(ApiCoorporationRole role) {
            coorporationBuilder.addRoleAtBase(role);
            return this;
        }

        public Builder addCoorporationRoleAtOther(ApiCoorporationRole role) {
            coorporationBuilder.addRoleAtOther(role);
            return this;
        }

        public Builder addCoorporationTitle(int titleId, String titleName) {
            coorporationTitles.add(new CoorporationTitle(titleId, titleName));
            return this;
        }

        public ApiCharacterSheet build() {
            skills = Collections.unmodifiableSet(skills);
            augmentations = Collections.unmodifiableSet(augmentations);
            certificates = Collections.unmodifiableSet(certificates);
            coorporationRoles = coorporationBuilder.build();
            coorporationTitles = Collections.unmodifiableSet(coorporationTitles);
            return new ApiCharacterSheet(this);
        }
    }

}
